package ca.cbc.medialib.entity;

import org.hibernate.annotations.AccessType;

import javax.persistence.*;
import javax.xml.bind.annotation.*;

import java.io.Serializable;
import java.util.*;

/**
 * @author Arash Bizhanzadeh <arash.bizhan-zadeh@cbc.ca>
 *         Date: 31/12/10
 *         Time: 11:31 AM
 *         Copyrighted to CBC. All rights reserved.
 */
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@Entity
public class Category implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 7909213900961217486L;
    @XmlAttribute
    private long id;
    @XmlElement
    private String title;
    @XmlElement
    private String fullTitle;
    @XmlElement
    private String description;
    @XmlElement
    private String bigBoxUrl;
    @XmlElement
    private String bannerAdUrl;
    @XmlElement
    private String bannerAdUrlForIPhone;
    @XmlElement
    private String thumbnailUrl;
    @XmlElementWrapper(name = "sponsors")
    @XmlElement(name = "sponsor")
    private List<Sponsor> sponsors;
    private Category parent;
    @XmlElementWrapper(name = "medias")
    @XmlElement(name = "media")
    private List<Media> medias;
    @XmlElementWrapper(name = "categories")
    @XmlElement(name = "category")
    private List<Category> children;

    private String sortField;
    private String sortOrder;
    @XmlElement
    private String groupLevel;
    @XmlElement
    private String groupOrder;

    private Category() {
        children = new ArrayList<Category>();
        medias = new ArrayList<Media>();
        sponsors = new ArrayList<Sponsor>();
    }

    public Category(long id, String title, String fullTitle, String description, String bigBoxUrl, String bannerAdUrl, String bannerAdUrlForIPhone, String thumbnailUrl) {
        this();
        this.setId(id);
        this.setTitle(title);
        this.setFullTitle(fullTitle);
        this.setDescription(description);
        this.setBigBoxUrl(bigBoxUrl);
        this.setBannerAdUrl(bannerAdUrl);
        this.setbannerAdUrlForIPhone(bannerAdUrlForIPhone);
        this.setThumbnailUrl(thumbnailUrl);
    }

    public void addChild(Category child) {
        child.setParent(this);
    }

    public void addMedia(Media media) {
        media.addCategory(this);
    }

    public void addSponsor(Sponsor s) {
        this.sponsors.add(s);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Category category = (Category) o;

        if (fullTitle != null ? !fullTitle.equals(category.fullTitle) : category.fullTitle != null) return false;
        if (id != category.getId()) return false;

        return true;
    }

    @Column(name = "banner_ad_url")
    public String getBannerAdUrl() {
        return bannerAdUrl;
    }
    
    @Column(name = "banner_ad_url_for_iphone")
    public String getBannerAdUrlForIPhone() {
    	return bannerAdUrlForIPhone;
    }

    @Column(name = "big_box_url")
    public String getBigBoxUrl() {
        return bigBoxUrl;
    }

    @OneToMany(mappedBy = "parent")
    @AccessType("field")
    public List<Category> getChildren() {
        return children;
    }

    public String getDescription() {
        return description;
    }

    @Column(name = "full_title")
    public String getFullTitle() {
        return fullTitle;
    }

    @Id
    public long getId() {
        return id;
    }

    @ManyToMany(mappedBy = "categories")
    @AccessType("field")
    public List<Media> getMedias() {
        return medias;
    }

    @ManyToOne
    @JoinColumn(name = "parent_id")
    @AccessType("field")
    public Category getParent() {
        return parent;
    }

    @Column(name = "sort_field")
    public String getSortField() {
        return sortField;
    }

    @Column(name = "sort_order")
    public String getSortOrder() {
        return sortOrder;
    }
    
    @Column(name = "group_level")
    public String getGroupLevel() {
        return groupLevel;
    }
    
    @Column(name = "group_order")
    public String getGroupOrder() {
        return groupOrder;
    }

    @ElementCollection
    @CollectionTable(name = "sponsor", joinColumns = @JoinColumn(name = "category_id"))
    @AttributeOverrides({
            @AttributeOverride(name = "imageUrl", column = @Column(name = "image_url")),
            @AttributeOverride(name = "url", column = @Column(name = "url"))})
    public List<Sponsor> getSponsors() {
        return sponsors;
    }

    @Column(name = "thumbnail_url")
    public String getThumbnailUrl() {
        return thumbnailUrl;
    }

    public String getTitle() {
        return title;
    }

    @Override
    public int hashCode() {
        int result = fullTitle != null ? fullTitle.hashCode() : (int) (id % 1000l);
        result = 31 * result;
        return result;
    }

    protected void internallAddMedia(Media media) {
        this.medias.add(media);
    }

    protected void internallRemoveMedia(Media media) {
        this.medias.remove(media);
    }

    public void removeChild(Category child) {
        if (children.contains(child)) {
            child.setParent(null);
        }
    }
    
    public void removeAllChildren() {
    	children = new ArrayList<Category>();
    }
    
    public void removeAllMedias() {
    	medias = new ArrayList<Media>();
    }

    public void removeMedia(Media media) {
        media.removeCategory(this);
    }


    public void setBannerAdUrl(String bannerAdUrl) {
        this.bannerAdUrl = bannerAdUrl;
    }
    
    public void setbannerAdUrlForIPhone(String bannerAdUrlForIPhone) {
        this.bannerAdUrlForIPhone = bannerAdUrlForIPhone;
    }

    public void setBigBoxUrl(String bigBoxUrl) {
        this.bigBoxUrl = bigBoxUrl;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setFullTitle(String fullTitle) {
        this.fullTitle = fullTitle;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setParent(Category parent) {
        if (this.parent != null) {
            this.parent.children.remove(this);
        }
        this.parent = parent;
        if (parent != null) {
            parent.children.add(this);
        }
    }

    public void setSortField(String sortField) {
        this.sortField = sortField;
    }

    public void setSortOrder(String sortOrder) {
        this.sortOrder = sortOrder;
    }
    
    public void setGroupLevel(String groupLevel) {
    	this.groupLevel = groupLevel;
    }
    
    public void setGroupOrder(String groupOrder) {
    	this.groupOrder = groupOrder;
    }

    public void setSponsors(List<Sponsor> l) {
        sponsors = l;
    }

    public void setThumbnailUrl(String thumbnailUrl) {
        this.thumbnailUrl = thumbnailUrl;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
